package org.threads.threadpool;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Model of ProcessingThread, which obtains tasks from queue
 * and processes it.
 * 
 * @author oler
 */
public class ProcessingThread implements Runnable {

    /**
     * Queue with waiting tasks to be processed.
     */
    private final TasksQueue processQueue;
    
    /**
     * Time of task processing. Have to be passed
     * to constructor.
     */
    private long processingTime;

    /**
     * Common constructor.
     * 
     * @param processQueue queue with tasks
     * @param processingTime time of task processing
     * @throws IllegalArgumentException if queue is <code>null</code>
     */
    public ProcessingThread(final TasksQueue processQueue, long processingTime)
            throws IllegalArgumentException {

        if (processQueue == null) {
            throw new IllegalArgumentException("Queue object cannot be equal to null!");
        }

        this.processQueue = processQueue;
        setProcessingTime(processingTime);
    }

    /**
     * Retrieves time of tasks processing.
     * 
     * @return time in milliseconds
     */
    public float getProcessingTime() {
        return processingTime;
    }

    /**
     * Sets time of tasks processing.
     *
     * @param processingTime time in milliseconds
     * @throws IllegalArgumentException if time is less then zero
     */
    public void setProcessingTime(long processingTime)
            throws IllegalArgumentException {

        if (processingTime < 0) {
            throw new IllegalArgumentException("Processing time cannot be less then zero!");
        }

        this.processingTime = processingTime;
    }

    /**
     * Entry point for custom thread.
     */
    @Override
    public void run() {

        while (true) {

            Integer process = null;

            synchronized (processQueue) {

                if (processQueue.isEmpty()) {
                    continue;
                }

                process = (Integer) processQueue.getProcess();
            }

            try {

                System.out.println(Thread.currentThread().getName() + ":  "
                        + "START processing task [ " + process + " ]");

                Thread.sleep(processingTime);

                System.out.println(Thread.currentThread().getName() + ":  "
                        + "END processing task [ " + process + " ]");

            } catch (InterruptedException ex) {
                Logger.getLogger(TaskGenerationThread.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

    }
}
